package com.yunqian.web;

import com.yunqian.exception.ActionException;
import com.yunqian.jwt.JwtUser;
import com.yunqian.redot.constant.BooleanStatus;
import com.yunqian.redot.constant.ConstantKey;
import com.yunqian.redot.domain.Users;
import com.yunqian.redot.service.UsersService;
import com.yunqian.util.validate.Validator;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Date;

/**
 * 登录控制器
 */
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private UsersService userService;

    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 登录
     *
     * @param user
     * @param req
     * @param res
     * @return
     * @throws AuthenticationException
     */
    @RequestMapping(value="/login",method=RequestMethod.POST)
    public Users login(@RequestBody Users user, HttpServletRequest req,
                         HttpServletResponse res) throws AuthenticationException{

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user.getName(), user.getPassword());
        try {
            Authentication authentication = authenticationManager.authenticate(authRequest);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            JwtUser jwtUser = (JwtUser)authentication.getPrincipal();
            Users users = userService.getById(jwtUser.getId());
            if(Validator.equals(users.getStatus(), BooleanStatus.NO.getCode())){
                throw new ActionException("账号已被禁用，请联系管理员激活");
            }
            String token = Jwts.builder()
                    .setSubject(user.getName())
                    .setExpiration(new Date(System.currentTimeMillis() + ConstantKey.TOKEN_EXPIRATION_ADMIN))
                    //采用什么算法是可以自己选择的，不一定非要采用HS512
                    .signWith(SignatureAlgorithm.HS512, ConstantKey.SIGNING_KEY)
                    .compact();
            res.addHeader("Authorization", "Bearer " + token);
            return users;
        } catch (BadCredentialsException ex) {
            throw new BadCredentialsException("密码输入错误");
        } catch (UsernameNotFoundException ex) {
            throw new UsernameNotFoundException("用户名不存在");
        }
    }

    /**
     * 退出
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value="/logout", method = RequestMethod.POST)
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "true";
    }

    @PostMapping("/sign_up")
    public Users signUp(@RequestBody @Valid Users user) {
        user.setPassword(DigestUtils.md5DigestAsHex((user.getPassword()).getBytes()));
        return userService.save(user);
    }

}
